package com.zhuxin.common;


import com.CommWxApplication;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.soecode.wxtools.api.WxConsts;
import com.soecode.wxtools.api.WxService;
import com.soecode.wxtools.bean.KeyWord;
import com.soecode.wxtools.bean.KfSender;
import com.soecode.wxtools.bean.SenderContent;
import com.soecode.wxtools.exception.WxErrorException;
import com.zhuxin.medical.model.po.CommWxUser;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.util.*;

public class UtilTools {

	/**
	 * Md5密码加密
	 * @param str
	 * @return
	 */
	public static String Md5(String str) { 
        MessageDigest messageDigest = null; 
 
        try { 
            messageDigest = MessageDigest.getInstance("MD5"); 
            messageDigest.reset(); 
            messageDigest.update(str.getBytes("UTF-8")); 
        } catch (NoSuchAlgorithmException e) { 
            System.out.println("NoSuchAlgorithmException caught!"); 
            System.exit(-1); 
        } catch (UnsupportedEncodingException e) { 
            e.printStackTrace(); 
        } 
        byte[] byteArray = messageDigest.digest(); 
        StringBuffer md5StrBuff = new StringBuffer(); 
        for (int i = 0; i < byteArray.length; i++) {             
            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) 
                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i])); 
            else 
                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); 
        } 
        return md5StrBuff.toString(); 
    }
	/**
	 * 获取访问用户IP地址
	 * @param request
	 * @return
	 */
	public static String getClientIp(HttpServletRequest request){
		String ip = request.getHeader("x-forwarded-for"); 
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		    ip = request.getHeader("Proxy-Client-IP"); 
		} 
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		    ip = request.getHeader("WL-Proxy-Client-IP"); 
		} 
		if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
		    ip = request.getRemoteAddr(); 
		}
		if(ip!=null && ip.indexOf(",")!=-1)ip=ip.split(",")[0];//分割代理地址
		return ip;
	}
	
	
	/**
	 * 复制文件
	 * @param sourceFile	源文件
	 * @param targetFile	目标文件
	 * @throws IOException
	 */
	public static void copyFile(File sourceFile, File targetFile) throws IOException {
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            // 新建文件输入流并对它进行缓冲
            inBuff = new BufferedInputStream(new FileInputStream(sourceFile));

            if(!targetFile.exists()){
            	targetFile.mkdirs();
            	targetFile.delete();
            	targetFile.createNewFile();
            }
            // 新建文件输出流并对它进行缓冲
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));

            // 缓冲数组
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inBuff.read(b)) != -1) {
                outBuff.write(b, 0, len);
            }
            // 刷新此缓冲的输出流
            outBuff.flush();
        } finally {
            // 关闭流
            if (inBuff != null)
                inBuff.close();
            if (outBuff != null)
                outBuff.close();
        }
    }
	/**
	 * 随机字符串
	 * @param length
	 * @return
	 */
	public static String RandomString(int length) { 
	    /*StringBuffer buffer = new StringBuffer("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); */
		StringBuffer buffer = new StringBuffer("0123456789");
	    StringBuffer sb = new StringBuffer(); 
	    Random r = new Random(); 
	    int range = buffer.length(); 
	    for (int i = 0; i < length; i ++) { 
	        sb.append(buffer.charAt(r.nextInt(range))); 
	    } 
	    return sb.toString(); 
	}

	/**
	 * 数字转换为2位小数的Double类型
	 * @param number
	 * @return
	 */
	public static Double getRoundHalfUp(Object number){
		return new BigDecimal((Double)number).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	public static String randomNumber(int length) {
	    StringBuffer buffer = new StringBuffer("0123456789");
	    StringBuffer sb = new StringBuffer();
	    Random r = new Random();
	    int range = buffer.length();
	    for (int i = 0; i < length; i ++) {
	        sb.append(buffer.charAt(r.nextInt(range)));
	    }
	    return sb.toString();
	}
	/**
	 * 读文本文件,仅限文本。
	 * @param filePath 文件路径
	 * @return
	 */
	public static String readTXTFile(String filePath,String encode){
		File file=new File(filePath);
		StringBuffer sb=new StringBuffer();
		try {
			BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(file), encode));
			String line=null;
			while((line=br.readLine())!=null){
				sb.append(line);
				sb.append("\n");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sb.toString();
	}
	/**
	 * 替换字符串
	 * @param sourceStr		源字符串
	 * @param regularMap	<被替换的字符串,替换成的字符串>
	 * @return
	 */
	public static String replaceStr(String sourceStr,Map<String, String> regularMap){
		Iterator<String> keys=regularMap.keySet().iterator();
		while(keys.hasNext()){
			String key = keys.next();
			sourceStr=UtilTools.replaceStr(sourceStr, key, regularMap.get(key));
		}
		return sourceStr;
	}
	/**
	 * 替换字符串
	 * @param sourceStr	源字符串
	 * @param from		要替换的目标字符串
	 * @param to		要替换的字符串
	 * @return
	 */
	public static String replaceStr(String sourceStr,String from,String to){
		StringBuffer buf =new StringBuffer(sourceStr);
		int i = 0;
		if ((i = sourceStr.indexOf(from, i)) >= 0) {
			char[] cSrc = sourceStr.toCharArray();
			char[] cTo = to.toCharArray();
			int len = from.length();
			buf = new StringBuffer(cSrc.length);
			buf.append(cSrc, 0, i).append(cTo);
			i += len;
			int j = i;
			while ((i = sourceStr.indexOf(from, i)) > 0) {
				buf.append(cSrc, j, i - j).append(cTo);
				i += len;
				j = i;
			}
			buf.append(cSrc, j, cSrc.length - j);
		}
		return buf.toString();
	}
	/**
	 * 写文本文件,仅限文本。
	 * @param path 文本路径
	 * @param context	内容
	 * @throws IOException
	 */
	public static void writeTXTFile(String path,String context,String encode) throws IOException{
		File f = new File(path);
		if(!f.exists()){
			f.mkdirs();
			f.delete();
			f.createNewFile();
		}else{
			f.delete();
			f.createNewFile();
		}
		BufferedWriter output = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(f), encode));
		output.write(context);
		output.flush();
		output.close();
	}
	

    public static boolean isNullOrBlank(String str) {
        return (str == null || "".equals(str.trim()));
    }

    public static boolean isNullOrBlank(Long str) {
        return str == null;
    }
    


    public static String formatDouble(String doubleStr, String format) {
        DecimalFormat decimalFormat = new DecimalFormat(format);
        if (UtilTools.isNullOrBlank(doubleStr)) {
            return "";
        }
        try {
            return decimalFormat.format(Double.parseDouble(doubleStr.trim()));
        } catch (Exception e) {
            return doubleStr;
        }
    }

    public static String formatDouble(Double src,String format){
    	DecimalFormat decimalFormat = new DecimalFormat(format);
		 if(null == src ){
			 return null;
		 }
		return decimalFormat.format(src);
	 }
    /**
     * 删除文件或文件夹
     * @param file
     */
	public static void deleteFile(File file) {
		if (file.exists()) {
			if (file.isFile()) {
				file.delete();
			} else if (file.isDirectory()) {
				File files[] = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					deleteFile(files[i]);
				}
			}
			file.delete();
		} else {
			System.out.println("所删除的文件不存在！" + '\n');
		}
	}


    /**
     * 格式化数值:采用向上进1处理非0小数
     *
     * @param val Double
     * @return
     */
    public static Double roundup(Double val) {
        return new BigDecimal(val).setScale(0, BigDecimal.ROUND_UP).doubleValue();
    }

    /**
     * 原页参数回传
     * @param request
     */
    public static void callBackRequest(HttpServletRequest request){
    	Iterator<String> it = request.getParameterMap().keySet().iterator();
		while(it.hasNext()){
			String rkey =  it.next();
			request.setAttribute(rkey, request.getParameter(rkey));
		}
    }

    /**
     * 加百分号
     * @param str
     * @param addflag 0：前后都加,1:前面加,2:后面加
     */
    public static String addPerSign(String str,int addflag){
    	String result=str;
    	if(!UtilTools.isNullOrBlank(str)){
    		StringBuilder sb=new StringBuilder(str);
    		result=addflag==0?sb.insert(0, '%').append('%').toString():addflag==1?sb.insert(0, '%').toString():addflag==2?sb.append('%').toString():sb.toString();
    	}
    	return result;
    }


    /**
	   * 从request中取出表单设置属性字符串
	   * @param request
	   * @return
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	   */
	  public static String getFormParm(HttpServletRequest request) throws Exception{
		  StringBuilder sb = new StringBuilder();
		  String result = "";
		  for (Enumeration enumeration =request.getParameterNames();
		      enumeration.hasMoreElements();) {
		          Object obj = enumeration.nextElement();
		          String name = obj.toString();
		          sb.append(","+name);
//		          String s =new String(request.getParameterValues((String) obj)[0].getBytes("ISO-8859-1"),"utf-8");
//		          System.out.println("Parameter name =" + obj.toString() + ", Parameter value =" + s);
		  } 
		  if(sb.length()>0){
			  result = sb.substring(1);
		  }
		  return result;
	  }
    

    
	 /**
	  * 将list<String> 转成 逗号分隔的string
	  * @param strList
	  * @return
	  */
	 public static String listToStr(List<String> strList){
		 if(strList.size()<1){
			 return "";
		 }
		 StringBuffer sb = new StringBuffer();
		 for (String str : strList) {
			sb.append(str+", ");
		 }
		 String str = sb.toString();
		 return str.substring(0, str.length()-1);
	 }
	 
	
    /**
     * 将Double数值四舍五入到指定小数位
     *
     * @param val
     * @param scale
     * @return
     */
    public static Double setScale(Double val, int scale) {
        return new BigDecimal(val).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static Double setScale(Double val) {
        return setScale(val, 4);
    }


	/**
	 * 获取request
	 * @return
	 */
	public static HttpServletRequest getRequest(){
		ServletRequestAttributes sa=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
		HttpServletRequest request = null;
		if(sa!=null) {
			request = sa.getRequest();
		}
		return request;
    }

	/**
	 * 序列化对象
	 * @param object
	 * @return
	 */
	public static byte[] serialize(Object object) {
		ObjectOutputStream oos = null;
		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			byte[] bytes = baos.toByteArray();
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 反序列化对象
	 * @param bytes
	 * @return
	 */
	public static Object deserialize(byte[] bytes) {
		ByteArrayInputStream bais = null;
		try {
			bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = new ObjectInputStream(bais);
			return ois.readObject();
		} catch (Exception e) {

		}
		return null;
	}

    /**
     * 带x的表达式代入计算
     *
     * @param expression g(x)=(x+1000)*0.8-100+50 这种形式的表达式
     * @param xVal       待代入表达式中的x值
     * @return
     */
//    public static Double caculateExpression(String expression, Double xVal) {
//        try {
//            Expression exp = ExpressionFactory.createExpression(expression);
//            Parameters parameters = ExpressionFactory.createParameters();
//            parameters.addParameter("x", NumberFactory.createReal(xVal));
//            Double result = exp.evaluate(parameters).getRealValue();
//            //logger.info("表达式计算结果,expression:" + expression + ";x=" + xVal + ";result=" + result);
//            return result;
//        } catch (Exception e) {
//            logger.info("表达式计算失败,expression:" + expression + ";x=" + xVal, e);
//        }
//        return 0d;
//    }

    /**
     * 拿UUID
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().toUpperCase();
    }

    /**
     * 检查List集合里面是否包含重复值
     * str为数据基本类型
     * @param str
     * @return
     */
    public static boolean checkRepeat(List<Object> str){
        Integer size = str.size();
        Integer sum = 0;
        Object []obj = str.toArray();
        Object temp = obj[0];
        for(int i=0;i<str.size();i++){
            if(obj[i].equals(temp)){
                sum++;
            }
        }
        return sum==size;
    }

    /**
     * json格式的实体类List<T> 转 List<T>
     */
    public static <T> List<T> jsonToList(String jsonString, Class<T> T) {
        @SuppressWarnings("unchecked")
        List<T> ts = new Gson().fromJson(jsonString,new TypeToken<List<T>>(){}.getType());
        return ts;
    }

	/**
	 * 发送POST请求
	 * @return
	 */
	public static ReqObject POST(String url){
		return new ReqObject(url);
	}




	/**
	 * 根据浏览器设置下载文件名编码
	 * @param request
	 * @param response
	 * @param filename
	 * @throws Exception
	 */
	public static void setDownloadFileName(HttpServletRequest request, HttpServletResponse response, String filename) throws Exception {
		//判断浏览器是否是Safari,如果是则用另外的编码方式编码文件名,防止下载中文乱码
		//2018-04-09 我靠...chrome居然有Safari关键字...
		String ua=request.getHeader("User-Agent");
		Boolean isSafari=(ua.indexOf("Safari")!=-1 && ua.indexOf("Chrome")==-1?true:false);
		if(isSafari)response.setHeader("Content-disposition", "attachment;filename="+ new String(filename.getBytes("UTF-8"),"ISO-8859-1"));
		else response.setHeader("Content-disposition", "attachment;filename="+ java.net.URLEncoder.encode(filename, "UTF-8"));
	}

	/**
	 * 实体对象转成Map
	 * @param obj 实体对象
	 * @return
	 */
	public static Map<String, KeyWord> object2Map(Object obj) {
		Map<String, KeyWord> map = new HashMap<>();
		if (obj == null) {
			return map;
		}
		Class clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				map.put(field.getName(), (KeyWord) field.get(obj));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	/**
	 * Map转成实体对象
	 * @param map map实体对象包含属性
	 * @param clazz 实体对象类型
	 * @return
	 */
	public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
		if (map == null) {
			return null;
		}
		Object obj = null;
		try {
			obj = clazz.newInstance();

			Field[] fields = obj.getClass().getDeclaredFields();
			for (Field field : fields) {
				int mod = field.getModifiers();
				if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
					continue;
				}
				field.setAccessible(true);
				field.set(obj, map.get(field.getName()));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}
	//拿当前用户的openid

	public static void sendKfMsg(String openid,String msg){
		KfSender sender = new KfSender();
		sender.setTouser(openid);
		sender.setMsgtype(WxConsts.MASS_MSG_TEXT);
		sender.setText(new SenderContent.Text(msg));
		sender.setCustomservice(new SenderContent.CustomService("kf2001@linyukeji007"));
		try {
			CommWxApplication.ctx.getBean(WxService.class).sendMessageByKf(sender);
		} catch (WxErrorException e) {
			e.printStackTrace();
		}
	}

}
